
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

extern "C"{
#include <event.h>
#include <event2/util.h>
}

using namespace std;

typedef struct sockaddr client;

void send_msg_cb(int fd, short events, void* arg)
{
	char msg[1024] = {0};
	int ret = read(fd, msg, sizeof(msg));
	if (ret <= 0)
	{
		perror("read fail");
		exit(1);
	}

	int sockfd = *((int*)arg);
	write(sockfd, msg, ret);
	cout<<"write:"<<msg<<endl;
}

void read_msg_cb(int fd, short events, void *arg)
{
	char msg1[1024] = {0};

	int len = read(fd, msg1, sizeof(msg1) - 1);
	if (len <= 0)
	{
		perror("read error");
		exit(1);
	}

	msg1[len] = '\0';
	cout<<"read is ok, msg:"<<msg1<<endl;
}

int connect_ser(const char* server_ip, const int port)
{
	int sockfd, status;
	struct sockaddr_in sock;

	memset(&sock, 0, sizeof(sock));

	sock.sin_family = AF_INET;
	sock.sin_port = htons(port);
	status = inet_aton(server_ip, &sock.sin_addr);

	if (status == 0)
	{		
		return -1;
	}

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == sockfd)
	{
		perror("socket is error");
		exit(-1);
	}

	status = connect(sockfd, (client*)&sock, sizeof(sock));
	if (-1 == status)
	{
		perror("connect");
		close(sockfd);
		return -1;
	}

	evutil_make_socket_nonblocking(sockfd);
	return sockfd;
}

int main(int argc, char **argv)
{
	if (argc < 3)
	{
		cout<<"please input two param:"<<endl;
		return -1;
	}

	int sockfd = connect_ser(argv[1], atoi(argv[2]));
	if (-1 == sockfd)
	{
		cout<<"connect is error"<<endl;
		return -1;
	}

	struct event_base *base = event_base_new();
	struct event *ev1 = event_new(base, sockfd, EV_READ|EV_PERSIST, read_msg_cb, NULL);
	event_add(ev1, NULL);

	struct event* ev2 = event_new(base, STDIN_FILENO,
							EV_READ|EV_PERSIST, send_msg_cb,
							(void*)&sockfd);
	event_add(ev2, NULL);
	event_base_dispatch(base);
	cout<<"ending>>>>"<<endl;
	return 0;
}


